home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
pascal
/
xlibpas2.zip
/
XLA2.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-06-08
|
28KB
|
1,278 lines
{╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ XLIB v2.0 for BORLAND/TURBO PASCAL 7.0 ║
║ Tristan Tarrant ( tristant@cogs.susx.ac.uk ) ║
║ ║
╠══════════════════════════════════════════════════════════════════════════╣
║ Credits : ║
║ Michael Abrash - Concept and Algorithms ║
║ Themie Gouthas - Original code ║
║ Michael McKenzie - More code ║
║ Tore Bastiansen - Virtual VSync Handler code ║
║ Andy Tam/Douglas Webb - LZS compression ║
╚══════════════════════════════════════════════════════════════════════════╝}
{$G+,N-,E-}
Unit XLA2;
Interface
Uses
XMisc2, Dos;
Const
None = 0;
LZS = 1;
Best = 8; {Not Used}
Type
XLAOutProcType = procedure( var Data; size : word );
XLAInProcType = procedure( var Data; size : word; var actual : longint );
Var
ModeUsed : word;
XLAOutProc : XLAOutProcType;
XLAInProc : XLAInProcType;
Function XLZSSave( FName : string ) : boolean;
Function XLZSLoad( FName : string ) : boolean;
procedure XPrintDir;
function XCloseArchive : boolean;
function XUpdateArchive( filename : string ) : boolean;
function XOpenArchive( filename : string ) : boolean;
function XLAGet( fname : string ) : boolean;
function XLAPut( fname : string; mode : word ) : boolean;
function XEndArchive : boolean;
function XCreateArchive( filename : string ) : boolean;
function XLAGetFileInfo( fname : string; var origsize, compsize : longint; mode : word ) : boolean;
function XLAFindFirst( pattern : string; var match : string ) : boolean;
function XLAFindNext( var match : string ) : boolean;
Implementation
const
TableSize = 5003;
LargestCode = 4095;
NoCode = -1;
N = 4096;
F = 18;
THRESHOLD = 2;
NUL = N * 2;
BUFSIZE = 1024;
InBufPtr : WORD = BUFSIZE;
InBufSize : WORD = BUFSIZE;
OutBufPtr : WORD = 0;
Type
PWorkspace = ^TWorkspace;
TWorkspace = record
TextBuf : Array[0.. N + F - 2] OF byte;
Left,Mom: Array [0..N] OF word;
Right: Array [0..N + 256] OF word;
end;
THeader = record
sig : array[0..3] of char;
posdir, sizedir : longint;
end;
TFile = record
name : array[0..11] of char;
posfile, sizefile, sizecomp : longint;
algorithm : word;
end;
PXLADir = ^TXLADir;
TXLADir = record
item : TFile;
next : PXLADir;
end;
Var
XLAFile : File;
Header : THeader;
XLADir, CurrentDir : PXLADir;
TotalSize, BytesWritten : longint;
printcount, height,
matchPos, matchLen,
lastLen, printPeriod : WORD;
opt : BYTE;
SearchPattern : string;
Workspace : PWorkspace;
codeBuf: Array [0..16] of BYTE;
Inbuf,OutBuf : Array[0..PRED(BUFSIZE)] of BYTE;
ArchiveOpen : boolean;
Procedure InitBuffers;
var
tmp : ^byte;
begin
while true do
begin
new( Workspace );
if ofs(Workspace^)<>0 then
begin
dispose( Workspace );
new( tmp );
end else break;
end;
end;
Procedure CleanUp;
begin
Dispose( Workspace );
end;
procedure CleanUpAll;
var
tmp : PXLADir;
begin
while XLADir<>nil do
begin
tmp := XLADir^.next;
dispose( XLADir );
XLADir := tmp;
end;
CleanUp;
end;
Function MemoryReadChunk: word;
var
Actual : longint;
begin
XLAInProc( InBuf, BufSize, Actual );
TotalSize := TotalSize + Actual;
MemoryReadChunk := Actual;
end;
Procedure MemoryGetc; Assembler;
asm
push bx
mov bx, inBufPtr
cmp bx, inBufSize
jb @getc1
push cx
push dx
push di
push si
call MemoryReadChunk
pop si
pop di
pop dx
pop cx
mov inBufSize, ax
or ax, ax
jz @getc2
xor bx, bx
@getc1:
mov al, [Offset InBuf + bx]
inc bx
mov inBufPtr, bx
pop bx
clc
jmp @end
@getc2:
pop bx
stc
@end:
end;
Function DiskReadChunk: word;
var
Actual : WORD;
begin
if Bufsize > TotalSize then
Actual := TotalSize
else
Actual := BufSize;
if Actual > 0 then BlockRead(XLAFile,InBuf,Actual);
TotalSize := TotalSize - Actual;
DiskReadChunk := Actual;
end;
Procedure DiskGetc; Assembler;
asm
push bx
mov bx, inBufPtr
cmp bx, inBufSize
jb @getc1
push cx
push dx
push di
push si
call DiskReadChunk
pop si
pop di
pop dx
pop cx
mov inBufSize, ax
or ax, ax
jz @getc2
xor bx, bx
@getc1:
mov al, [Offset InBuf + bx]
inc bx
mov inBufPtr, bx
pop bx
clc
jmp @end
@getc2:
pop bx
stc
@end:
end;
Procedure MemoryWriteout;
begin
XLAOutProc( OutBuf, OutBufPtr );
BytesWritten := BytesWritten + OutBufPtr;
end;
Procedure MemoryPutc; Assembler;
asm
push bx
mov bx, outBufPtr
mov [OFFSet OutBuf + bx], al
inc bx
cmp bx, BUFSIZE
jb @putc1
mov OutBufPtr,BUFSIZE
push cx
push dx
push di
push si
call MemoryWriteOut
pop si
pop di
pop dx
pop cx
xor bx, bx
@putc1:
mov outBufPtr, bx
pop bx
end;
Procedure DiskWriteout;
var
Actual : WORD;
begin
BlockWrite(XLAFile,OutBuf,OutBufPtr,Actual);
BytesWritten := BytesWritten + OutBufPtr;
end;
Procedure DiskPutc; Assembler;
asm
push bx
mov bx, outBufPtr
mov [OFFSet OutBuf + bx], al
inc bx
cmp bx, BUFSIZE
jb @putc1
mov OutBufPtr,BUFSIZE
push cx
push dx
push di
push si
call DiskWriteOut
pop si
pop di
pop dx
pop cx
xor bx, bx
@putc1:
mov outBufPtr, bx
pop bx
end;
PROCEDURE LZSInitTree; Assembler;
ASM
cld
les ax, Workspace
mov di, offset TWorkspace.Right
add di, (N + 1) * 2
mov cx, 256
mov ax, NUL
rep stosw
mov di, offset TWorkspace.mom
mov cx, N
rep stosw
END;
PROCEDURE LZSSplay; Assembler;
ASM
les si, Workspace
@Splay1:
mov si, es:[Offset TWorkspace.Mom + di]
cmp si, NUL
ja @Splay4
mov bx, es:[Offset TWorkspace.Mom + si]
cmp bx, NUL
jbe @Splay5
cmp di, es:[Offset TWorkspace.Left + si]
jne @Splay2
mov dx, es:[Offset TWorkspace.Right + di]
mov es:[Offset TWorkspace.Left + si], dx
mov es:[Offset TWorkspace.Right + di], si
jmp @Splay3
@Splay2:
mov dx, es:[Offset TWorkspace.Left + di]
mov es:[Offset TWorkspace.Right + si], dx
mov es:[Offset TWorkspace.Left + di], si
@Splay3:
mov es:[Offset TWorkspace.Right + bx], di
xchg bx, dx
mov es:[Offset TWorkspace.Mom + bx], si
mov es:[Offset TWorkspace.Mom + si], di
mov es:[Offset TWorkspace.Mom + di], dx
@Splay4:
jmp @end
@Splay5:
mov cx, es:[Offset TWorkspace.Mom + bx]
cmp di, es:[Offset TWorkspace.Left + si]
jne @Splay7
cmp si, es:[Offset TWorkspace.Left + bx]
jne @Splay6
mov dx, es:[Offset TWorkspace.Right + si]
mov es:[Offset TWorkspace.Left + bx], dx
xchg bx, dx
mov es:[Offset TWorkspace.Mom + bx], dx
mov bx, es:[Offset TWorkspace.Right + di]
mov es:[Offset TWorkspace.Left +si], bx
mov es:[Offset TWorkspace.Mom + bx], si
mov bx, dx
mov es:[Offset TWorkspace.Right + si], bx
mov es:[Offset TWorkspace.Right + di], si
mov es:[Offset TWorkspace.Mom + bx], si
mov es:[Offset TWorkspace.Mom + si], di
jmp @Splay9
@Splay6:
mov dx, es:[Offset TWorkspace.Left + di]
mov es:[Offset TWorkspace.Right + bx], dx
xchg bx, dx
mov es:[Offset TWorkspace.Mom + bx], dx
mov bx, es:[Offset TWorkspace.Right + di]
mov es:[Offset TWorkspace.Left + si], bx